#include "RingQueue.hpp"
#include <ctime>
#include <unistd.h>
#include <sys/types.h>
#include "Task.hpp"

void *productor_routinue(void *args)
{
    // //version1  单生产 单消费
    // ring_queue<int> *rq = static_cast<ring_queue<int> *>(args);
    // while(true)
    // {
    //     //产生数据，放入到环形队列中
    //     sleep(3);
    //     int data = rand()%10+1;
    //     rq->Push(data);
    //     std::cout<<"生产者生产数据: "<<data<<std::endl;

    // }
    // return nullptr;

    //version 2 多生产 多消费 并且任务改为具体的函数
    ring_queue<Task> *rq = static_cast<ring_queue<Task> *>(args);
    while(true)
    {
        int x = rand()%10+1;
        int y = rand()%5+1;
        char op=opera[rand()%5];
        Task t(x, y, op, myMath);
        rq->Push(t);
        std::cout<<"生产者生产数据: "<<t.Tostring()<<std::endl;
        
    }
    return nullptr;

}
void *comsumer_routinue(void *args)
{
    // ///version 1 单生产 单消费
    // ring_queue<int> *rq = static_cast<ring_queue<int> *>(args);
    // //开始push和pop
    // while(true)
    // {
    //     int data;
    //     rq->Pop(&data);
    //     std::cout<<"消费者消费数据 :"<<data<<std::endl;
    //     // sleep(1);
    // }
    // return nullptr;
    //version 2 多生产 多消费 并且任务改为具体的函数
    ring_queue<Task> *rq = static_cast<ring_queue<Task> *>(args);
    while(true)
    {   
        Task t;
        rq->Pop(&t);
        std::cout<<"消费者消费数据: "<<t()<<std::endl;
    }
    return nullptr;
}

int main()
{
    //对于单生产，单消费而言，只有生产和消费之间的竞争关系
    //pthread_t c, p;   
    //如果对于多生产和多消费而言，满足321原则，3种竞争关系：生产与生产之间，消费与消费之间，生产和消费之间的竞争和  2种角色：生产者和消费者 1种公共资源：环形队列
    //此时 对于这个环形队列而言，就是一个公共资源，需要加锁，防止多个生产线程同时进去，改变n
    pthread_t c[4],p[5];

    srand((unsigned int)time(nullptr)^getpid()^pthread_self());  //抛下随机数种子

    //ring_queue<int> *rq = new ring_queue<int>();
    ring_queue<Task> *rq = new ring_queue<Task>();
    // 创建消费者和生产者线程
    for(int i=0;i<5;i++)  pthread_create(p+i, nullptr, productor_routinue, rq);
    for(int i=0;i<4;i++)  pthread_create(c+i, nullptr, comsumer_routinue, rq);

    for(int i=0;i<5;i++)  pthread_join(p[i], nullptr);
    for(int i=0;i<4;i++)  pthread_join(c[i], nullptr);

    delete rq;

    return 0;
}